home *** CD-ROM | disk | FTP | other *** search
- UNIT BPTrap;
-
- { Trap runtime errors, Version 1.0
- Copyright (C) 1991-1996 by Frank Heckenbach, heckenb@mi.uni-erlangen.de
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, version 1, for NON-COMMERCIAL use.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. }
-
- {$IFNDEF VER70}
- This unit was tested only with Borland Pascal 7.0. You can use it with other
- versions by commenting these two lines, but at your own risk!
- {$ENDIF}
-
- INTERFACE
-
- FUNCTION Trap:Boolean; FAR;
- {* Returns False on installation.
- * After trapping a runtime error it jumps back to where the function was
- called returning True.
- * The procedure that calls Trap must NOT return as long as Trap is installed
- (so it is safest to call Trap from the main program, if possible)!
- * You must call this function AFTER installing all other Exitprocs (if any).
- * In Real mode: You must NOT call it from an overlayed unit.
- * In Protected mode and Windoze: You must call it from a code segment with
- the following attributes: FIXED PRELOAD PERMANENT. (I am not sure if this
- is really necessary...).}
-
- FUNCTION UnTrap:Boolean;
- {Returns True iff Trap could be uninstalled.}
-
- IMPLEMENTATION
-
- TYPE ptrrec=RECORD ofs,sgm:Word END;
-
- CONST
- addrsave:Pointer=NIL;
- codesave:Word=0;
-
- VAR
- exitsave,trapaddr:Pointer;
- trapsp,trapbp:Word;
-
- {$S-}
- PROCEDURE Trapexit; FAR;
- BEGIN
- IF Erroraddr<>NIL
- THEN {Trapping runtime error}
- BEGIN
- {Install Trapexit again (in case another runtime error occurs later)!}
- Exitproc:=@Trapexit;
-
- {Keep error address and exit code and reset these variables}
- addrsave:=Erroraddr;
- codesave:=Exitcode;
- Erroraddr:=NIL;
- Exitcode:=0;
-
- {If you want, you can do something here to indicate the user that an
- error occurred. You could e.g. pop up a message telling the user to
- quit the program asap and report the error to the programmer.}
-
- ASM
- {Load the saved SP and BP registers}
- MOV SP,trapsp
- MOV BP,trapbp
-
- {Continue at saved address returning True}
- MOV AL,1
- JMP [trapaddr]
- END
- END
-
- ELSE {Programm finished without an error}
- BEGIN
- {Continue with other exit procs}
- Exitproc:=exitsave;
-
- {Restore error address and exit code of the last trapped error, if any}
- IF addrsave<>NIL THEN
- BEGIN
- Erroraddr:=addrsave;
- Exitcode:=codesave
- END
- END
- END;
-
- FUNCTION Trap:Boolean; ASSEMBLER;
- ASM
- {Install Trapexit as an Exitproc}
- MOV AX,OFFSET Trapexit
- MOV DX,SEG Trapexit
- CMP Exitproc.ptrrec.ofs,AX
- JNE @1
- CMP Exitproc.ptrrec.sgm,DX
- JE @2
- @1:XCHG Exitproc.ptrrec.ofs,AX
- XCHG Exitproc.ptrrec.sgm,DX
- MOV exitsave.ptrrec.ofs,AX
- MOV exitsave.ptrrec.sgm,DX
-
- {Save SP and BP registers and the return address}
- @2:MOV trapbp,BP
- MOV SI,SP
- {$IFDEF WINDOWS}
- ADD SI,4
- ADD trapbp,6
- {$ENDIF}
- LES DI,SS:[SI]
- MOV trapaddr.ptrrec.ofs,DI
- MOV trapaddr.ptrrec.sgm,ES
- ADD SI,4
- MOV trapsp,SI
-
- {Return False}
- XOR AX,AX
- END;
-
- FUNCTION UnTrap:Boolean;
- BEGIN
- IF Exitproc=@Trapexit
- THEN
- BEGIN
- Exitproc:=exitsave;
- UnTrap:=True
- END
- ELSE UnTrap:=False
- END;
- END.
-